package com.katze.common.config;

import com.katze.common.http.HttpUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 说  明：
 * 作  者：zf.zeng
 * 日  期：2022-12-20 (星期二)
 **/
@ConditionalOnProperty(value = "app.mode", havingValue = "client")
public class WebMvcConfigurerAdapter implements WebMvcConfigurer {

    @Value("${app.mvc.allow}")
    private final Set<String> allow = new HashSet<>();

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new URLInterceptor(this.allow)).addPathPatterns("/**");
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }

    protected static class URLInterceptor implements HandlerInterceptor {
        private final Set<String> ip;

        public URLInterceptor(Set<String> ip) {
            this.ip = Objects.requireNonNull(ip);
        }

        //在请求处理之前进行调用（Controller方法调用之前）
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
            if (this.ip.isEmpty() || this.ip.contains(HttpUtils.getRemoteAddress(request))) {
                return true;
            } else {
                response.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
                return false;
            }
        }
    }
}
